今天是要來優化留言區域,做完留言功能後會發現並沒有即時更新,必須重整之後才會渲染出新的留言,所以要使用到firebase
提供的即時更新功能onSnapshot
。
onSnapshot()
可以一次監聽多個檔案,官方文件上是用
import { collection, query, where, onSnapshot } from "firebase/firestore";
const q = query(collection(db, "cities"), where("state", "==", "CA"));
const unsubscribe = onSnapshot(q, (querySnapshot) => {
const cities = [];
querySnapshot.forEach((doc) => {
cities.push(doc.data().name);
});
console.log("Current cities in CA: ", cities.join(", "));
});
跟我寫的code差異很大,這邊改寫找了很多資料才知道要怎麼改…
useEffect(()=>{
const querySnapshot = getDocs(collection(docRef,"comments")).then((snapshot)=>{
return snapshot
}).then((commentSnapshot)=>{
const commsntData = commentSnapshot.docs.map((doc) => {
return doc.data()
});
setHistoryComment(commsntData)
})
},[])
在這篇文章中有說到
getDocs()
: 有資料更新的時候需要重整頁面才能看到新的資料
onSnapshot()
:只要有任何改變,他可以自動在不重整的狀態下呈現新的資料
所以我就直接把getDocs
用onSnapshot(query())
替代,onSnapshot
不能使用then
,但在第二的參數可放入一個函式,將上述整合後改寫成以下:
useEffect(()=>{
onSnapshot(query(collection(docRef,"comments")),(docsSnap)=>{
const commentData = docsSnap.docs.map((doc) => {
return doc.data()
})
setHistoryComment(commentData)
})
},[])
最後!!! 文章即時更新完成,但順序需要修改一下,這邊用到了orderBy的功能,他的位置可以放到query裡面,這邊可以參考官方資料。
useEffect(()=>{
onSnapshot(query(collection(docRef,"comments"), orderBy('createdAt', 'desc')),(docsSnap)=>{
const commentData = docsSnap.docs.map((doc) => {
return doc.data()
})
setHistoryComment(commentData)
})
},[])